package com.sawgdev.android.bokuiki.activity;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import org.apache.commons.lang3.StringUtils;

import android.app.PendingIntent;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;
import com.sawgdev.android.bokuiki.R;
import com.sawgdev.android.bokuiki.bean.BeanConfig;
import com.sawgdev.android.bokuiki.bean.BeanHistory;
import com.sawgdev.android.bokuiki.common.Constants;
import com.sawgdev.android.bokuiki.common.Constants.EnumStatus;
import com.sawgdev.android.bokuiki.common.Util;
import com.sawgdev.android.bokuiki.common.database.BKDBHelper;
import com.sawgdev.android.bokuiki.common.database.BkpfDao;
import com.sawgdev.android.bokuiki.common.gps.MapOverlay;
import com.sawgdev.android.bokuiki.common.mail.Mail;

/**
 * ドコイキマップ表示画面
 */
public class ActMap extends MapActivity implements LocationListener {

	MapView aMapView;
	MapController aMapController;
	MyLocationOverlay myOverlay;
	LocationManager mLocationManager;
	PendingIntent pIntent;

	// 初回位置情報取得フラグ
	private int getPointFlg;
	private double oldLng;
	private double oldLat;

	// 2点間直線用
	private List<Overlay> listOverlay;

	// アラート通知を行う半径（ｍ）
	private final int alert = 1500;

	// 設定情報
	private BeanConfig config;

	// 位置情報表示用
	TextView tv;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		// 基本情報を設定
		setConfig();

		// 地図の利用を可能とする
		aMapView = (MapView) findViewById(R.id.myMapView);

		// 地図の初期表示時の縮尺を設定
		aMapView.getController().setZoom(18);

		// 地図のズーム機能を有効
		aMapView.setBuiltInZoomControls(true);
		aMapController = aMapView.getController();
		myOverlay = new MyLocationOverlay(this, aMapView);

		// 位置情報取得をオン
		myOverlay.enableMyLocation();

		// 現在位置表示機能をオン
		myOverlay.enableCompass();

		// 現在情報を自動でスクロールして中心に表示する
		myOverlay.runOnFirstFix(new Runnable() {
			public void run() {
				GeoPoint myPoint = myOverlay.getMyLocation();
				aMapController.animateTo(myPoint);
			}
		});

		// 位置表示用のオーバーレイを登録
		aMapView.getOverlays().add(myOverlay);

		// 1.MapViewのOverlay一覧を取得する
		listOverlay = aMapView.getOverlays();

		// ロケーションマネージャの取得
		mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

		/** テキストビューの取得 */
		tv = (TextView) findViewById(R.id.text);
		tv.setText("位置情報が未取得です");
	}

	/**
	 * <pre>
	 * アラート通知を行う距離（ｍ）を設定
	 * 基本設定がされていない場合は、画面を閉じて基本設定を促す。
	 * </pre>
	 */
	private void setConfig() {
		BKDBHelper helper = BKDBHelper.getInstance(this);
		SQLiteDatabase db = helper.getReadableDatabase();
		BkpfDao bkpfDao = new BkpfDao(db);
		config = bkpfDao.selConfig();

		if (StringUtils.isEmpty(config.getName())) {
			Toast.makeText(this, "基本設定をしてください。", Toast.LENGTH_LONG).show();
			this.finish();
		}
	}

	/** isRouteDisplayedメソッドを実装する */
	protected boolean isRouteDisplayed() {
		return false;
	}

	/** 位置情報更新の設定 */
	public void onResume() {
		super.onResume();
		if (mLocationManager != null) {
			mLocationManager.requestLocationUpdates(
					LocationManager.GPS_PROVIDER, Constants.UPDAT_TIME,
					Constants.UPDAT_DISTANCE, this);
		}
	}

	@Override
	protected void onPause() {
		super.onPause();
		if (mLocationManager != null) {
			mLocationManager.removeUpdates(this);
		}
	}

	/**
	 * 位置情報が更新された場合、以下の処理を行う ・取得した緯度、経度、住所、ステータスをDBへ格納 ・前回位置情報と今回位置情報を線で結び軌跡を表示
	 */
	@Override
	public void onLocationChanged(Location location) {

		// 自宅（基準地点）の緯度・経度
		double startLatitude = config.getLat();
		double startLongitude = config.getLng();
		// 現在地の緯度・経度
		double endLatitude = 0;
		double endLongitude = 0;

		GeoPoint geoPointFrom = null;
		GeoPoint geoPointTo = null;
		// ステータス変数
		int status = 0;

		GeoPoint gp = new GeoPoint((int) (location.getLatitude() * 1E6),
				(int) (location.getLongitude() * 1E6));

		// 緯度の取得
		endLatitude = gp.getLatitudeE6() / 1E6;

		// 経度の取得
		endLongitude = gp.getLongitudeE6() / 1E6;

		// 取得した緯度、経度、住所、ステータスをDBへ格納
		BeanHistory beanHistory = new BeanHistory();
		beanHistory.setCreateDate(Util.getSystemDateStr());
		beanHistory.setLatitude(endLatitude);
		beanHistory.setLongitude(endLongitude);
		beanHistory.setAltitude(location.getAltitude());

		// Geocoderを使用して住所(地名)を取得する
		StringBuffer buff = new StringBuffer();
		try {
			Geocoder geocoder = new Geocoder(this, Locale.getDefault());
			List<Address> addresses = geocoder.getFromLocation(endLatitude,
					endLongitude, 1);
			for (Address addr : addresses) {
				// 住所(地名)取得処理
				int index = addr.getMaxAddressLineIndex();
				for (int i = 1; i <= index; ++i) {
					buff.append(addr.getAddressLine(i));
				}
			}
			beanHistory.setLocation(buff.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}
		if (startLatitude != 0.0 && startLongitude != 0.0) {
			float[] results = { 0, 0, 0 };
			Location.distanceBetween(startLatitude, startLongitude,
					endLatitude, endLongitude, results);

			// 基準地点から1500m離れるとアラートメールを送信
			// アラートの場合はstatusを2に設定
			if (results != null && results[0] >= alert) {
				StringBuilder sb = new StringBuilder();
				sb.append("基準地点から1500M以上離れています。\n");
				sb.append("現在位置は");
				sb.append(beanHistory.getLocation());
				sb.append("です。\n");

				Mail mail = new Mail(this);
				mail.sendMail(config.getEmail(), "[ぼくいきアラートメール]", sb.toString());
				status = EnumStatus.STATUS_DANGER.ordinal();
			} else {
				status = EnumStatus.STATUS_NORMAL.ordinal();
			}
		}
		beanHistory.setCreateDate(Util.getSystemDateStr());
		beanHistory.setStatus(status);
		BKDBHelper helper = BKDBHelper.getInstance(this);
		SQLiteDatabase db = helper.getWritableDatabase();
		BkpfDao bkpfDao = new BkpfDao(db);
		bkpfDao.insHistory(beanHistory);

		// 地図の中心位置を移動する
		aMapController.animateTo(gp);

		// 最後に取得した緯度・経度をテキストビューへ出力
		tv.setText("経度：" + String.valueOf(endLatitude) + "，経度："
				+ String.valueOf(endLongitude));

		// 始点と終点の緯度経度をGePointに変換し、HogeOverlayクラスに渡す
		if (getPointFlg == 0) {
			geoPointFrom = new GeoPoint((int) (endLatitude * 1E6),
					(int) (endLongitude * 1E6));
			geoPointTo = new GeoPoint((int) (endLatitude * 1E6),
					(int) (endLongitude * 1E6));
			getPointFlg = 1;
		} else {
			geoPointFrom = new GeoPoint((int) (oldLat * 1E6),
					(int) (oldLng * 1E6));
			geoPointTo = new GeoPoint((int) (endLatitude * 1E6),
					(int) (endLongitude * 1E6));
		}
		MapOverlay mapOverlay = new MapOverlay(geoPointFrom, geoPointTo);

		// 取得しておいたMapViewのOverlay一覧に、MapOverlayインスタンスをadd
		listOverlay.add(mapOverlay);

		// 前回位置情報退避
		oldLat = endLatitude;
		oldLng = endLongitude;

	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		mLocationManager = null;
	}

	public void onProviderDisabled(String provider) {
	}

	public void onProviderEnabled(String provider) {
	}

	public void onStatusChanged(String provider, int status, Bundle extras) {
	}
}